﻿using HslCommunication.Profinet.Melsec;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace XingLucifer.Devices
{
    public class MelsecA1ENetMachine : PLCBase
    {

        MelsecA1ENet socket;//创建对象
        public int ID { get; set; }
        public string IP { get; set; }
        public int PORT { get; set; }
        public int Timeout { get; set; }
        bool IsRunning { get; set; }
        bool IsConnected { get; set; }
        object locker = new object();
        public MelsecA1ENetMachine(int id, string ip, int timeout = 400)
        {
            var vals = ip.Split(':');
            IP = vals[0].Trim();
            PORT = int.Parse(vals[1]);
            Timeout = timeout;
            ID = id;
            //IsConnected = Connection();
        }
        object lockSocket = new object();
        public bool Connection()
        {
            try
            {
                socket = new MelsecA1ENet(IP, PORT);
                socket.ConnectTimeOut = Timeout;
                socket.ReceiveTimeOut = 700;
                socket.ByteTransform.IsStringReverseByteWord = true;
                socket.ConnectionId = ID.ToString();
                IsConnected = socket.ConnectServer().IsSuccess;
                return true;
            }
            catch (Exception ex)
            {
                return false;
            }
        }

        /// <summary>
        ///   方法来将字符串转换为一个 List<UInt16>，其中每两个字符被组合成一个 UInt16 值，每两个字符存储在一个字内，一个字符存储在低八位，另一个字符存储在高八位
        /// </summary>
        /// <param name="addr"></param>
        /// <param name="values"></param>
        /// <returns></returns>
        public bool WriteStringAsUInt16(string addr, string values)
        {
            try
            {
                var vals = new List<UInt16>();

                for (int i = 0; i < values.Length; i += 2)
                {
                    char lowChar = values[i];
                    char highChar = (i + 1 < values.Length) ? values[i + 1] : '\0';  // '\0' 表示空字符

                    byte lowByte = (byte)(lowChar & 0xFF);      // 取低八位
                    byte highByte = (byte)(highChar & 0xFF);    // 取高八位

                    UInt16 combinedValue = (UInt16)((lowByte << 8) | highByte);  // 组合成一个 UInt16 值，互换高低字节
                    vals.Add(combinedValue);
                }

                return socket.Write(addr, vals.ToArray()).IsSuccess;
            }
            catch (Exception ex)
            {
                return false;
            }

        }

        public bool WriteString(string addr, string values)
        {
            try
            {
                return socket.Write(addr, values).IsSuccess;
            }
            catch (Exception ex)
            {
                return false;
            }

        }
        public bool ReadBool(string addr)
        {
            try
            {
                var data = socket.ReadBool(addr);
                while (!data.IsSuccess)
                {
                    data = socket.ReadBool(addr);
                }
                if (data.IsSuccess)
                {
                    return data.Content;
                }
                else
                {

                }

                return false;
            }
            catch (Exception ex)
            {
                return false;
            }

        }
        int i = 0;
  
        public List<Int32> ReadInt32(string addr, int count)
        {
            try
            {

                int limitation = 3;
                lock (lockSocket)
                {

                    var data = socket.ReadInt32(addr, (ushort)count);
                    while (!data.IsSuccess && limitation > 0)
                    {
                        data = socket.ReadInt32(addr, (ushort)count);
                        limitation--;
                    }
                    if (data.IsSuccess)
                    {
                        return data.Content.ToList();
                    }
                    else
                    {

                        return null;
                    }
                }


            }
            catch (Exception ex)
            {
                IsConnected = false;
                return null;
            }
        }
        public string ReadString(string addr, int count)
        {

            try
            {
                lock (lockSocket)
                {
                    var data = socket.ReadString(addr, (ushort)count);
                    while (!data.IsSuccess)
                    {
                        data = socket.ReadString(addr, (ushort)count);
                    }
                    if (data.IsSuccess)
                    {
                        return data.Content.Replace("\0", "");
                    }
                    else
                    {
                        return null;
                    }
                }

            }
            catch (Exception ex)
            {
                return null;
            }

        }



        public void Close()
        {
            if (socket != null)
            {
                try
                {
                    socket.ConnectClose();
                    socket.Dispose();
                }
                catch (Exception)
                {

                }
                socket = null;
            }
            IsConnected = false;
        }
        public bool Write<T>(string addr, T[] values)
        {
            try
            {
                switch (values)
                {
                    case short[] shortValues:
                        return WriteToShort(addr, shortValues[0]);
                    case ushort[] ushortValues:
                        return WriteToUShort(addr, ushortValues[0]);
                    default:
                        throw new ArgumentException("不支持的类型");
                }
            }
            catch (Exception ex)
            {
                return IsConnected = false;
            }
        }

        private bool WriteToShort(string addr, short value)
        {
            lock (lockSocket)
            {
                var data = socket.Write(addr, value);
                while (!data.IsSuccess)
                {
                    data = socket.Write(addr, value);
                }

                return data.IsSuccess;
            }
        }
        private bool WriteToUShort(string addr, ushort value)
        {
            lock (lockSocket)
            {
                var data = socket.Write(addr, value);
                while (!data.IsSuccess)
                {
                    data = socket.Write(addr, value);
                }
                return data.IsSuccess;
            }
        }

        public bool ReadAndReturnBit(string addr)
        {
            throw new NotImplementedException();
        }
        public List<UInt32> ReadUInt32(string addr, int count)
        {
            int limitation = 3;
            try
            {
                lock(lockSocket)
                {
                    var data = socket.ReadUInt32(addr, (ushort)count);
                    while (!data.IsSuccess && limitation > 0)
                    {
                        data = socket.ReadUInt32(addr, (ushort)count);
                        limitation--;
                    }
                    if (data.IsSuccess)
                    {
                        return data.Content.ToList();
                    }
                    else
                    {

                        return null;
                    }

                }


            }
            catch (Exception ex)
            {
                IsConnected = false;
                return null;
            }
        }

        public List<ushort> Read(string addr, int count)
        {
            try
            {
                int limitation = 3;
                lock (lockSocket)
                {
                    var data = socket.ReadUInt16(addr, (ushort)count);
                    while (!data.IsSuccess && limitation > 0)
                    {
                        data = socket.ReadUInt16(addr, (ushort)count);
                        limitation--;
                    }
                    if (data.IsSuccess)
                    {
                        return data.Content.ToList();
                    }
                    else
                    {

                        return null;
                    }
                }


            }
            catch (Exception ex)
            {
                IsConnected = false;
                return null;
            }
        }


        public Task<List<ushort>> ReadAsync(string addr, int count)
        {
            throw new NotImplementedException();
        }

        public Task<bool> ConnectionAsync()
        {
            throw new NotImplementedException();
        }

        public string ToString(IEnumerable<ushort> values)
        {
            throw new NotImplementedException();
        }

        /// <summary>
        /// 清空地址，用于清空批次号、型号等
        /// </summary>
        /// <param name="addr"></param>
        /// <param name="length"></param>
        /// <returns></returns>
        public bool ClearPLCAddress(string addr, int length)
        {
            try
            {
                var vals = new UInt16[length];
                for (int i = 0; i < length; i++)
                {
                    vals[i] = 0;
                }

                return socket.Write(addr, vals).IsSuccess;
            }catch (Exception ex)
            {
                return false;
            }
          
        }

       
    }
}
